package net.ainom.scarab.xmlrpc;

import java.io.File;
import java.net.URL;
import java.util.Properties;
import java.util.StringTokenizer;

public class ScarabHook implements Hook {
    private static final String                   USAGE              = "Usage:\njava " + ScarabHook.class.getCanonicalName()
                                                                             + " REPOS_LOC REVISION ISSUE_TRACKING_URL\n";
    private static final String                   DEFAULT_PROPERTIES = "issue-tracking-scm-integration-default.properties";
    private static final String                   LOCAL_SETTINGS     = "local.properties.file";
    private static final String                   PROPS_KEY          = "props";
    private static final String                   ISSUE_URL_KEY      = "url";
    private static final String                   FILTERS_KEY        = "filters";
    private static final String                   USERNAME           = "username";
    private static final String                   PASSWORD           = "password";
    private AbstractScarabIssueTrackerIntegration integration        = new ScarabIssueTracker();

    public ScarabHook(String[] args) throws Exception {
        super();
        _setupHookFromParameters(args);
    }

    public void addFilter(Filter _filter) {
        integration.addFilter(_filter);
    }

    public void run() {
        Thread t = new Thread(integration);
        t.start();
    }

    /**
     * @TODO Here we'll get parameters and System properties to setup the hook
     * 
     * @param args
     * @throws Exception
     */
    protected void _setupHookFromParameters(String[] args) throws Exception {
        if (args.length < 2) {
            System.err.println(USAGE);
            System.exit(-1);
        }
        String repo = args[0];
        String rev = args[1];
        Properties baseDefaults = new Properties();
        baseDefaults.load(this.getClass().getResourceAsStream(DEFAULT_PROPERTIES));
        Properties props = new Properties(baseDefaults);
        String s = (System.getProperty(PROPS_KEY, baseDefaults.getProperty(LOCAL_SETTINGS)));
        if (s != null) {
            s = s.trim();
            props.load(this.getClass().getResourceAsStream(s));
        }

        URL url = getURLProperty(props, ISSUE_URL_KEY);
        long revision = Long.parseLong(rev);
        File f = new File(repo);
        if (!f.exists()) {
            System.err.println("Repo Location " + repo + " does not exist");
            System.exit(-1);
        }

        String x = getStringProperty(props, FILTERS_KEY);

        StringTokenizer st = new StringTokenizer(x, ", ");
        while (st.hasMoreTokens()) {
            Filter filter = null;
            String fclas = st.nextToken();
            Class c = Class.forName(fclas);
            if (Filter.class.isAssignableFrom(c)) {
                filter = (Filter) c.newInstance();
                try {
                    filter.setFilterProperties(props);
                } catch (Exception e) {
                    // Filter failed on "setFilterProperties" somehow.  This filter is now bad.
                    e.printStackTrace();
                    filter = null;
                }
            }
            if (filter != null)
                addFilter(filter);
        }
        try {
            integration.setUsername(getStringProperty(props, USERNAME));
        } catch (MissingPropertyException e) {
            // Don't worry
        }
        try {
            integration.setPassword(getStringProperty(props, PASSWORD));
        } catch (MissingPropertyException e) {
            // Don't worry
        }
        integration.setRev(revision);
        integration.setIssueTrackingActionUrl(url);
        integration.setRepo(f);
    }

    private URL getURLProperty(Properties props, String key) throws Exception {
        return new URL(getStringProperty(props, key));
    }

    private String getStringProperty(Properties props, String key) throws Exception {
        String s = props.getProperty(key);
        if (s != null) {
            s = s.trim();
        }
        String y = System.getProperty(key);
        if (y == null)
            y = "";
        y = y.trim();
        if (y.length() > 0)
            s = y;
        if (s.length() > 0)
            return s;
        throw new MissingPropertyException("Property " + key + " not found");
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            new ScarabHook(args).run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
